/**
 * 随机数[0,1),等概率与固定概率0，1发生器
 */
public class Random {
    public static void main(String[] args) {
        int[] count = new int[8];
        int testTime = 100000;
        //
        for (int i = 0; i < testTime; i++) {
            int num = y();
            count[num]++;
        }
        for (int i = 0; i < 2; i++) {
            System.out.println("y:" +i + " 次数：" + count[i]);
            System.out.println("y:" +(double) count[i] / (double) testTime);
        }
        //
        for (int i = 0; i < testTime; i++) {
            int num = f4();
            count[num]++;
        }
        for (int i = 0; i < 8; i++) {
            System.out.println("f4:" + i + " 次数：" + count[i]);
            System.out.println("f4:" + (double) count[i] / (double) testTime);
        }
    }

    //构造等概率0，1发生器
    public static int y() {
        int ans = 0;
        do {
            ans = x();
        } while (ans == x());
        if (ans == 0) {
            return 0;
        } else {
            return 1;
        }
    }

    //0，1发生器以固定概率（未知）返回
    public static int x() {
        return Math.random() < 0.88 ? 0 : 1;
    }


    /**
     * 构造0，1等概率发生器，实现区间数值等概率返回
     *
     * @return
     */
    //f1函数等概率[1,5]
    public static int f1() {
        return getNum(1, 5);
    }

    //由f1函数构造0，1发生器
    public static int f2() {
        int ans = 0;
        do {
            ans = f1();
        } while (ans == 3);
        return ans < 3 ? 0 : 1;
    }

    //二进制等概率构造数值范围[0-7]
    public static int f3() {
        int ans = (f2() << 2) + (f2() << 1) + f2();
        return ans;
    }

    //实现等概率[1,7]
    public static int f4() {
        int ans = 0;
        do {
            ans = f3();
        } while (ans == 0);
        return ans;
    }

    //等概率产生某取值范围内的一个整数
    public static int getNum(int min, int max) {
        return (int) (Math.random() * max) + min;
    }

}
